﻿using Common.Communi;
using Common.Communi.SerialPortCommonication;
using Common.Enum;
using ControllerManageServer.Controller;
using ControllerManageServer.Packet;
using Controller.Model;
using Controller.Utils;
using Controller.Enum;
using Leeder.Logger;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Common.Communi.Model;

namespace ControllerManageServer.Controller
{
    /// <summary>
    /// 普达RFID通讯帮助类
    /// </summary>
    internal class PradaSerialCommunicationController : SerialCommunication
    {
        #region 变量定义

        /// <summary>
        /// 日志对象
        /// </summary>
        private LogOperate _log;
        /// <summary>
        /// 数据包最小长度
        /// </summary>
        private int DATA_PACKET_MINIMUM_LENGTH = 6;

        #endregion  变量定义

        #region 构造函数

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="iSerialPortInfo">连番信息</param>
        /// <param name="iMode">连番命令模式</param>
        /// <param name="iDelayReceiveTime">延时接收时间</param>
        public PradaSerialCommunicationController(SerialPortInfoModel iSerialPortInfo, SerialCommunicationModeEnum iMode = 0, int iDelayReceiveTime = 20) 
            : base(iSerialPortInfo, iMode, iDelayReceiveTime)
        {
            _log = Log.GetLogger(GetType());

            CommunicationFrequency = 100;
            serialCommunicationMode = iMode;
            delayReceiveTime = iDelayReceiveTime;
        }

        #endregion 构造函数

        /// <summary>
        /// 解析报文
        /// </summary>
        /// <param name="iBuffer">数据报文</param>
        /// <returns></returns>
        protected override List<byte[]> PacketParsing(byte[] iBuffer) {
        //    _log.Debug($"Receive Data <> {ByteUtils.ByteArrayToHexString(iBuffer)}");
            PradaWatchCommunicationCommandEnum commandType;
            List<byte[]> result = new List<byte[]>();
            int pos = 0;
            int dataLength;
            while (true)
            {
                // 找到匹配的数据帧头
                while (iBuffer.Length - pos >= 2 && (iBuffer[pos] != PradaActionPacketModel.DATA_PACKET_HEAD[0] || iBuffer[pos + 1] != PradaActionPacketModel.DATA_PACKET_HEAD[1]))
                {
                    if (iBuffer[pos + 1] == PradaActionPacketModel.DATA_PACKET_HEAD[0]) pos += 1;
                    else pos += 2;
                }
                // 如果报文长度不足最短的长度则跳过
                if (iBuffer.Length - pos < DATA_PACKET_MINIMUM_LENGTH)
                {
                    pendingPacket = iBuffer.Skip(pos).Take(iBuffer.Length - pos).ToArray();
                    return result;
                }
                commandType = (PradaWatchCommunicationCommandEnum) iBuffer[pos + 2];
                switch (commandType) {
                    case PradaWatchCommunicationCommandEnum.RFID_DATA:
                        {
                            dataLength = DATA_PACKET_MINIMUM_LENGTH + sizeof(int);
                            result.Add(iBuffer.Skip(pos).Take(dataLength).ToArray());
                            pos += dataLength;
                        } break;
                    case PradaWatchCommunicationCommandEnum.ACK: {
                            dataLength = 2 + DATA_PACKET_MINIMUM_LENGTH;// 命令和结果
                            result.Add(iBuffer.Skip(pos).Take(dataLength).ToArray());
                            pos += dataLength;
                        }break;
                    case PradaWatchCommunicationCommandEnum.REQUEST_DISPLAY_DATA:
                        {
                            dataLength = DATA_PACKET_MINIMUM_LENGTH + 2;
                            result.Add(iBuffer.Skip(pos).Take(dataLength).ToArray());
                            pos += dataLength;
                        } break;
                    default:{
                        _log.Error($"undefined command type:{commandType}");
                        pos += 2;
                    } break;
                }
            }
        }

        ///// <summary>
        ///// 设置发送数据
        ///// </summary>
        ///// <param name="key"></param>
        ///// <param name="iPacket"></param>
        //public void SetSendData(string key, ServerPacketModel iPacket)
        //{
        //    SetSendData(iPacket.Serialize());
        //}

    }
}
